/*
	aco-netdesign -- Ant colony optimization solution to network design problem

	Copyright (C) 2008 Jeffrey Sharkey, http://jsharkey.org/
	
	Developed by Jeffrey Sharkey as part of his thesis work at Montana State
	University. His work was sponsored by the Western Transportation Institute,
	and was guided by advisor Doug Galarus. Other valuable guidance was
	provided by Dr. Bill Jameson and Gary Schoep. 

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "graph.h"
#include "util.h"
#include "solver.h"


#define IS_TABU -1024
#define NO_BANDWIDTH -2048
#define ENDGAME 1024


class SolutionACO;

class Ant : public Path, public Tagged {
public:
	SolutionACO* s;
	bool forceEndgame;
	double bandwidth;
	
	Ant(SolutionACO* s_, Vertex* start_);
	virtual ~Ant();
	
	bool finished();
	double localHeuristic(Edge* e);

	double mixedValue(Edge* e, SolutionACO* s);
	
};


class SolutionACO : public Solution {
public:
	Graph* g;
	Lookup* look;
	TimeRemaining* t;
	
	ulist<Ant*> ants;
	ulist<Ant*> unsolved;
	map<Vertex*, double> pheromones;
	map<Edge*, double> bandwidth;
	
	bool silent;
	
	SolutionACO(Graph* g_, Lookup* look_);
	//virtual ~SolutionACO();
	~SolutionACO();
	
	double globalHeuristic();
	void solve();
	bool solved();
	void iteration();
	
	inline void savePheromones(string filename) {

ofstream out(filename.c_str(), ofstream::out);
out.precision(8);

map<Vertex*, double>::iterator it;
for(it = pheromones.begin(); it != pheromones.end(); it++) {
	Vertex* v = (Vertex*)(*it).first;
	double value = (*it).second;
	out << v->id << "\t" << value << endl;
}

out.close();

	}

};


class SolverACO : public Solver {
public:
	bool silent;
	int generations;

	map<Vertex*, double> pheromones;
	static double minPher, defPher, maxPher, increment;
	static double alphaHeur, alphaPher, alphaRand, alphaPref;
	
	SolverACO(Graph* g_, Lookup* look_);
	virtual inline ~SolverACO() {
	}
	
	SolutionACO* fullSolve(int generations, int population);
	ulist<SolutionACO*> buildGeneration(int population);
	void updatePheromones(SolutionACO* s);
	SolutionACO* singleSolution();
	void dumpPheromones();
	
};




